<template>
  <el-dialog
    v-model="dialogVisible"
    class="person-selector-dialog"
    :close-on-click-modal="false"
    destroy-on-close
    :title="title"
    width="1000px"
    @close="handleDialogClose"
  >
    <div class="person-selector">
      <div class="selector-content">
        <!-- 左侧组织树 -->
        <div class="left-panel">
          <org-tree
            :model-value="currentDepartmentId"
            @load-end="loading = false"
            @load-start="loading = true"
            @node-click="handleNodeClick"
          />
        </div>

        <!-- 右侧用户列表 -->
        <div class="right-panel">
          <!-- 搜索区域 -->
          <search-form-component @reset="handleResetSearch" @search="handleSearchSubmit" />

          <!-- 用户表格 -->
          <div v-loading="tableLoading" class="user-table-container">
            <user-table
              ref="userTableRef"
              :data="userList"
              :loading="tableLoading"
              :multiple="!!props.multiple"
              :selected-users="selectedUsers"
              :total="total"
              @page-change="handlePageChange"
              @select-all="handleAddCurrentPageToSelection"
              @selection-change="handleTableSelectionChange"
              @size-change="handleSizeChange"
              @view-detail="handleViewUserDetail"
            />
          </div>
        </div>
      </div>

      <!-- 已选人员区域 -->
      <div v-show="selectedUsers.length > 0" class="selector-footer">
        <selected-user :users="selectedUsers" @remove="removeUser" />
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <div v-if="showEmptyWarning" class="empty-warning">请至少选择一个人员</div>
        <div class="button-group">
          <el-button @click="handleCancelButtonClick">取消</el-button>
          <el-button type="primary" @click="handleConfirmButtonClick">确定</el-button>
        </div>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import OrgTree from './components/OrgTree.vue'
import SearchFormComponent from './components/SearchForm.vue'
import SelectedUser from './components/SelectedUsers.vue'
import UserTable from './components/UserTable.vue'
import { usePersonSelector } from './composables/usePersonSelector'
import { useSearch } from './composables/useSearch'
import { useSelection } from './composables/useSelection'
import type { SearchForm, TreeNode, User } from './types'

const props = defineProps<{
  modelValue: boolean
  multiple?: boolean
  defaultSelected?: User[]
  maxSelection?: number
  allowEmpty?: boolean
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
  (e: 'confirm', users: string[]): void
  (e: 'cancel'): void
  (e: 'close'): void
  (e: 'view-detail', user: User): void
}>()

console.log('[index.vue setup] Initial props.multiple:', props.multiple)

// 用户表格引用
const userTableRef = ref<InstanceType<typeof UserTable> | null>(null)

// 引入组合式逻辑
const { userList, tableLoading, total, currentDepartmentId, isExternal, pageSize, loadTreeData, loadUserList, selectDepartment } =
  usePersonSelector()

const { selectedUsers, removeUser, clearSelection, initSelectedUsers, updateSelectionFromTable, addCurrentPageUsersToSelection } =
  useSelection(props.multiple, props.maxSelection || 0)

const { searchForm, resetSearch } = useSearch()

// 状态变量
const dialogVisible = ref(false)
const loading = ref(false)

// 计算属性
const title = computed(() => (props.multiple ? '选择人员（多选）' : '选择人员'))
const showEmptyWarning = computed(() => {
  return !props.allowEmpty && selectedUsers.value.length === 0
})

// Function to reconcile selected users (possibly partial) with loaded user list (full data)
const reconcileSelectedUsersWithLoadedData = () => {
  console.log('[reconcile] Starting. selectedUsers before:', JSON.stringify(selectedUsers.value.map((u) => ({ id: u.id, name: u.name }))))
  if (!selectedUsers.value || selectedUsers.value.length === 0 || !userList.value || userList.value.length === 0) {
    console.log('[reconcile] Skipping: No selected users or no loaded user list.')
    return // Nothing to reconcile or no data loaded yet
  }

  console.log('[reconcile] userList (source for reconciliation):', JSON.stringify(userList.value.map((u) => ({ id: u.id, name: u.name }))))

  const userMap = new Map(userList.value.map((u) => [u.id, u]))
  let needsUpdate = false

  const updatedSelectedUsers = selectedUsers.value.map((selUser) => {
    const fullUser = userMap.get(selUser.id)
    // If the selected user is missing a name AND we found a full user object with the same ID in the loaded list AND that full object has a name...
    if (fullUser && !selUser.name && fullUser.name) {
      console.log(`[reconcile] Updating user ${selUser.id} (${selUser.name}) with full data including name: ${fullUser.name}`)
      needsUpdate = true
      return fullUser // Use the complete user object from the loaded list
    }
    return selUser // Otherwise, keep the existing selected user object
  })

  console.log(
    '[reconcile] updatedSelectedUsers after mapping:',
    JSON.stringify(updatedSelectedUsers.map((u) => ({ id: u.id, name: u.name })))
  )
  console.log('[reconcile] needsUpdate flag:', needsUpdate)

  if (needsUpdate) {
    console.log('[reconcile] Applying updates to selectedUsers ref.')
    selectedUsers.value = updatedSelectedUsers // Assign the new array to trigger reactivity
  } else {
    console.log('[reconcile] No updates needed for selectedUsers names based on current userList.')
  }
  console.log('[reconcile] Finished. selectedUsers after:', JSON.stringify(selectedUsers.value.map((u) => ({ id: u.id, name: u.name }))))
}

// 监听model值变化
watch(
  () => props.modelValue,
  async (newVal) => {
    dialogVisible.value = newVal
    if (newVal) {
      // Initialize selection FIRST, possibly with partial data
      if (props.defaultSelected && props.defaultSelected.length > 0) {
        initSelectedUsers(props.defaultSelected)
        console.log('[watch modelValue] Initial selectedUsers after init:', JSON.stringify(selectedUsers.value))
      } else {
        // Ensure selection is clear if no default is provided
        clearSelection()
      }
      // Load initial page data and wait for it
      await loadInitialData()
      console.log('[watch modelValue] userList after loadInitialData:', JSON.stringify(userList.value))
      // Attempt to reconcile names using the loaded data
      reconcileSelectedUsersWithLoadedData()
    }
  }
)

// 监听对话框关闭
watch(dialogVisible, (newVal) => {
  if (!newVal) {
    emit('update:modelValue', false)
  }
})

// 初始化加载数据
const loadInitialData = async () => {
  loading.value = true
  try {
    await loadTreeData()

    // 初次加载时不指定部门ID，展示所有用户
    await loadUserList({
      page: 1,
      pageSize: pageSize.value,
      isExternal: false,
    })
  } catch (error) {
    console.error('初始化数据加载失败:', error)
    // 只有当真正发生错误时才显示错误提示
    if (error instanceof Error) {
      ElMessage.error('加载数据失败，请稍后重试')
    }
  } finally {
    loading.value = false
  }
}

// 组织树节点点击
const handleNodeClick = async (node: TreeNode) => {
  selectDepartment(node)
  console.log('选中部门:', node.label, 'ID:', node.id, '是否外部:', node.isExternal)

  // 加载该部门下的用户数据
  await loadUserList({
    deptId: node.id,
    isExternal: !!node.isExternal,
    page: 1,
    pageSize: pageSize.value,
  })
  reconcileSelectedUsersWithLoadedData()
}

// 搜索提交
const handleSearchSubmit = async (form: SearchForm) => {
  await loadUserList({
    deptId: currentDepartmentId.value || undefined,
    isExternal: isExternal.value,
    keyword: form.keyword,
    page: 1,
    pageSize: pageSize.value,
  })
  reconcileSelectedUsersWithLoadedData()
}

// 重置搜索
const handleResetSearch = async () => {
  resetSearch()
  await loadUserList({
    deptId: currentDepartmentId.value || undefined,
    isExternal: isExternal.value,
    page: 1,
    pageSize: pageSize.value,
  })
  reconcileSelectedUsersWithLoadedData()
}

// 初始化组件
onMounted(() => {
  if (props.modelValue) {
    // 初始化已选择的用户
    if (props.defaultSelected && props.defaultSelected.length > 0) {
      initSelectedUsers(props.defaultSelected)
    }
    // 加载初始数据
    loadInitialData()
  }
})

// UserTable勾选状态变更时调用 (currentPageTableSelection: 当前页勾选的用户)
const handleTableSelectionChange = (currentPageTableSelection: User[]) => {
  console.log('[index.vue] handleTableSelectionChange received:', JSON.stringify(currentPageTableSelection))
  updateSelectionFromTable(currentPageTableSelection, userList.value)
}

// UserTable发出"全选当前页"时调用 (通常是表格内的一个"全选当前页"按钮)
const handleAddCurrentPageToSelection = () => {
  addCurrentPageUsersToSelection(userList.value)
}

// 分页相关
const handlePageChange = async (page: number) => {
  await loadUserList({
    deptId: currentDepartmentId.value || undefined,
    isExternal: isExternal.value,
    keyword: searchForm.value.keyword,
    page,
    pageSize: pageSize.value,
  })
  reconcileSelectedUsersWithLoadedData()
}

const handleSizeChange = async (size: number) => {
  await loadUserList({
    deptId: currentDepartmentId.value || undefined,
    isExternal: isExternal.value,
    keyword: searchForm.value.keyword,
    page: 1,
    pageSize: size,
  })
  reconcileSelectedUsersWithLoadedData()
}

// 点击"确定"按钮
const handleConfirmButtonClick = () => {
  console.log('[index.vue] handleConfirmButtonClick triggered.')
  console.log('[index.vue] Current selectedUsers:', JSON.stringify(selectedUsers.value.map((u) => u.id)))
  console.log('[index.vue] props.multiple:', props.multiple)
  if (!props.allowEmpty && selectedUsers.value.length === 0) {
    ElMessage.warning('请至少选择一个人员')
    return
  }

  // 确认时，总是返回用户ID的数组
  emit(
    'confirm',
    selectedUsers.value.map((u) => u.id)
  )
  dialogVisible.value = false
}

// 点击"取消"按钮
const handleCancelButtonClick = () => {
  clearSelection()
  emit('cancel')
  dialogVisible.value = false
}

// Dialog关闭时（如点击X）
const handleDialogClose = () => {
  emit('close')
  // v-model的watch会自动同步 update:modelValue
}

// 查看用户详情
const handleViewUserDetail = (user: User) => {
  emit('view-detail', user)
}
</script>

<style scoped>
.person-selector-dialog {
  overflow: hidden;
  border-radius: 12px;
}

.person-selector {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 200px);
  max-height: 680px;
  overflow: hidden;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 16px rgba(0, 0, 0, 0.08);
}

.selector-content {
  display: flex;
  flex: 1;
  gap: 0;
  min-height: 0;
}

.left-panel {
  box-sizing: border-box;
  display: flex;
  flex-shrink: 0;
  flex-direction: column;
  width: 280px;
  padding: 16px 0 16px 16px;
  background: #fafbfc;
  border-right: 1px solid #f0f0f0;
}

.right-panel {
  box-sizing: border-box;
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  padding: 16px 16px 0 16px;
  background: #fff;
}

.user-table-container {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.selector-footer {
  box-sizing: border-box;
  padding: 16px;
  margin-top: 16px;
  overflow-y: auto;
  background: #fafbfc;
  border-top: 1px solid #f0f0f0;
  border-radius: 0 0 10px 10px;
}

.dialog-footer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 0 0 0;
  background: #fff;
  border-top: 1px solid #ebeef5;
}

.empty-warning {
  padding-right: 16px;
  font-size: 14px;
  color: #f56c6c;
  text-align: right;
}

.button-group {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}

:deep(.el-dialog__body) {
  padding: 0;
}

:deep(.el-dialog__footer) {
  padding: 0 24px 24px 24px;
  border-top: none;
}

:deep(.el-dialog__header) {
  padding: 20px 24px;
  margin: 0;
  background-color: #fafbfc;
  border-bottom: 1px solid #f0f0f0;
}

:deep(.el-dialog__title) {
  font-size: 18px;
  font-weight: 600;
  color: #333;
}

:deep(.el-dialog__headerbtn) {
  top: 20px;
  right: 20px;
}

:deep(.el-table__row:hover) {
  background: #f5f7fa !important;
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 12px;
}
</style>
